package com.bbcare.huaian.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.alibaba.fastjson.JSONObject;
import cn.hutool.setting.dialect.Props;
import cn.hutool.setting.dialect.PropsUtil;

import com.bbcare.oms.plat.entity.Account;
import com.bbcare.oms.plat.service.IAccountService;


/**
 * 淮安的SSO控制器。
 */
@Controller
@RequestMapping({"/sso"})
public class SSOController {
    private final static Log logger = LogFactory.getLog(SSOController.class);
    private final static String STATE = "bbcarefollowup20211203";
/*
    @Autowired
    private IAccountService accountService;
*/

    @RequestMapping({"/login"})
    public void getAuthCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("++++getAuthCode() is called.");
        Props props = PropsUtil.get("account.properties");
        final String authorize  = props.getStr("huaian_authorize_endpoint");
        final String clientId   = props.getStr("huaian_client_id");
        final String redirectUri= props.getStr("huaian_redirect_uri");
        final String urlEncoded = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8.toString());
        logger.info("authorizeurl:"+authorize);
        logger.info("clientId:"+clientId);
        logger.info("redirectUri:"+redirectUri);
        final String redirectUrl = authorize + "?client_id=" + clientId + "&redirect_uri=" + urlEncoded + "&response_type=code&state=" + STATE + "&scope=openid%20roles%20profile";
        logger.info("redirectUrl:"+redirectUrl);
        //注意，这里必须POST请求。
        response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
        response.setHeader("Location", redirectUrl);
        response.sendRedirect(redirectUrl);
    }

    @GetMapping(value = "/login2")
    public String ssologin(@RequestParam("code") final String code, @RequestParam("state") final String state, HttpSession httpSession, HttpServletRequest request) throws Exception
    {
        if (null == state || state.isEmpty() || !state.equalsIgnoreCase(STATE))   {
            throw new RuntimeException("请求参数state错误！！");
        }
        if (null == code || code.isEmpty())   {
            throw new RuntimeException("请求参数code错误！！");
        }
        logger.info("++++code:"+code+", state:"+state);

        Props props = PropsUtil.get("account.properties");
        final String clientId   = props.getStr("huaian_client_id");
        final String clientSecret   = props.getStr("huaian_client_secret");
        final String redirectUri= props.getStr("huaian_redirect_uri");
        final String tokenUrl   = props.getStr("huaian_token_endpoint");
        String param = "client_id="+clientId+"&client_secret="+clientSecret+"&grant_type=authorization_code&code="+code+"&redirect_uri="+redirectUri;
        final String tokenResp  = HttpUtil.sendPost(tokenUrl, param);
        JSONObject jsonobject = JSONObject.parseObject(tokenResp);
        final String accessToken = jsonobject.getString("access_token");
        logger.info("++++access_token:"+accessToken);

        //Step 5: Get userinfo.
        final String userInfoUrl = props.getStr("huaian_userinfo_endpoint");
        URL realUrl = new URL(userInfoUrl);
        URLConnection conn = realUrl.openConnection();
        conn.setRequestProperty("Authorization", "Bearer " + accessToken);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        PrintWriter out = new PrintWriter(conn.getOutputStream());
        out.print(param);
        out.flush();
        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
        String line;
        StringBuilder result = new StringBuilder();
        while ((line = in.readLine()) != null)  {
            result.append(line);
        }
        out.close();
        in.close();
        JSONObject userInfo = JSONObject.parseObject(result.toString());
        logger.info("++++HIS return userinfo is:"+userInfo.toString());
        final String ssoName = userInfo.getString("name");    //用户在SSO系统中的登录账号。
        logger.info("++++SSO name:"+ssoName);

        final String doctorUsername = props.getStr(ssoName);
        if (null == doctorUsername || doctorUsername.isEmpty()) {
            throw new RuntimeException("SSOName:"+ssoName+"无法映射到随访系统的用户！！");
        }

        return "redirect:/autoLogin.html?username=" + doctorUsername;
    }

}
